1 Why version control?

If an analysis was published and changes were made to the analysis script, we won’t be able to easily reproduce those results without knowing what was done to the script! GitHub provides us some safety for reproducibility by tracking changes to a shared repository. Even if someone deletes code from a file, we can revert to a previous version of the shared repository. Note that we’re not saving data to the repository, so make sure the file used lives where the script says.

We’re also able to review changes people make before they’re accepted to GitHub, which allows us to provide some quality control in the analyses we intend to publish.

2 High level overview

At a high level, GitHub is a tool that allows us to collaboratively track, manage, and use files. We clone a GitHub repository to our computer, and changes to those files on our computer are detected by Git, the underlying versioning software. We can upload those changes to GitHub, which tracks and shares what changes were made. The ‘Master” branch you see below is what is on GitHub. When you clone the repo to your computer, you’ll be cloning the master branch, and any changes you make will fork (see blue). People won’t see your changes until you commit to your cloned/local repository and ’push’ your changes back to the master branch. In order for someone to see your recently pushed changes, they need to pull after your changes are pushed to master. For example, Orange won’t see the changes Blue made because Orange didn’t pull from the master branch after Blue committed & pushed their changes back to the master branch.

If we want to implement a stricter standard of quality control, we can alternatively create a branch from master and request others to review our code using a ‘pull request.’ This would require others to review our code before our work is ‘pulled’ back into master. The diagram below still works. Though, instead of us pushing our forked changes to master, we’re explicitly creating a branch and requesting people to approve our changes and pull it back into master, rather than (implicitly) forking off master and pushing our changes back without review.

3 Getting set up

By now, you should have received an invite from our Enterprise GitHub to collaborate on the on a specific repository. Once you create an account, you will be able to access the GitHub repository. The one shown below is the hillblom_data repo, which is now renamed.. That should look like this:

Once you have your account set up and are able to access the link provided above to navigate to the specific repository, it’s time to download the GitHub Desktop App.

After the GitHub app is downloaded, go to back to the repository. From there, you’ll click the green button, ‘Code.’

And click, ‘Open with GitHub Desktop.’

That’ll open the GitHub App (if you approve permission), and you’ll be greeted with this screen. Set the local path to whichever folder you want to work from. For this iteration, I created an ‘Enterprise’ folder. Though, I’m typically working from my Documents folder.

The final local path should be something similar to :

  • on Mac: /Users/yourusername/Documents/reponame
  • on PC: C:Users\yourusername\Documents\reponame

From here, hit ‘Clone.’

4 Test it out!

4.1 Open the local directory where you cloned the repository

4.2 Find the file ‘write_your_name.txt’ in the path:

  • on Mac: /Users/yourusername/Documents/reponame
  • on PC: C:Users\yourusername\Documents\reponame

4.3 Write your name.

4.4 Close the file.

4.5 Open the GitHub App.

4.6 Pull/fetch the most recent version of the master branch.

  • This is to ensure we are working from the most recent version of the master branch.

4.7 Commit changes to your local machine.

  • This records changes you made to the cloned version of the repository.
  • If left after this stage, people will not see your changes in the shared repository.

4.8 Finally, push your changes.

Now everyone can see your changes on the Github website or on their local machine if they pull/fetch. We’re able to track what changes were made and refer or revert back to previous versions of the files in the repository.

5 For more stringent quality control

5.1 Create a new branch

  • Click on the current branch.

  • Opt to create new branch

  • Name branch and confirm

5.2 Publish the new branch to our GitHub repo.

5.3 Now you can work in this branch as you would the original.

  • Your changes will be tracked, and you will need to commit your changes to the branch you’re working on.

  • Commit your changes to your local version of the branch

  • Push your changes to the online repository

5.4 When you’re ready for someone to review your code and merge the branch you created back to the origin, create a pull request.

  • This will take you to the GitHub website, where you’ll assign your reviewers and assignees. They’ll be the ones who review your code. Leave a brief description of your request and a more detailed explanation below if needed.

5.5 If you were assigned to a pull request, you’ll see these pages.

  • First, it’ll take you to the conversation page. However, you’ll want to take a look at the changes you’ve been assigned to review, which you can find in the ‘Files changed’ tab.
  • You’ll see the only change in this file was an added space. Additions are in green, and deletions/old code are in red.
  • Go to the ‘Review changes’

  • Leave you comments, requests, or approve the pull request.

5.6 Once your pull request is approved, merge the pull request back into the origin.

  • Confirm the merge.

5.7 Finally, you can delete the old branch.

  • This isn’t necessary, but it can help to keep things organized.

6 That’s the end!

LS0tCnRpdGxlOiAiU2V0dGluZyB1cCB2ZXJzaW9uIGNvbnRyb2wiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIGhpZ2hsaWdodDogaGFkZG9jawotLS0KCiMgV2h5IHZlcnNpb24gY29udHJvbD8KCklmIGFuIGFuYWx5c2lzIHdhcyBwdWJsaXNoZWQgYW5kIGNoYW5nZXMgd2VyZSBtYWRlIHRvIHRoZSBhbmFseXNpcyBzY3JpcHQsIHdlIHdvbid0IGJlIGFibGUgdG8gZWFzaWx5IHJlcHJvZHVjZSB0aG9zZSByZXN1bHRzIHdpdGhvdXQga25vd2luZyB3aGF0IHdhcyBkb25lIHRvIHRoZSBzY3JpcHQhIEdpdEh1YiBwcm92aWRlcyB1cyBzb21lIHNhZmV0eSBmb3IgcmVwcm9kdWNpYmlsaXR5IGJ5IHRyYWNraW5nIGNoYW5nZXMgdG8gYSBzaGFyZWQgcmVwb3NpdG9yeS4gRXZlbiBpZiBzb21lb25lIGRlbGV0ZXMgY29kZSBmcm9tIGEgZmlsZSwgd2UgY2FuIHJldmVydCB0byBhIHByZXZpb3VzIHZlcnNpb24gb2YgdGhlIHNoYXJlZCByZXBvc2l0b3J5LiBOb3RlIHRoYXQgd2UncmUgbm90IHNhdmluZyBkYXRhIHRvIHRoZSByZXBvc2l0b3J5LCBzbyBtYWtlIHN1cmUgdGhlIGZpbGUgdXNlZCBsaXZlcyB3aGVyZSB0aGUgc2NyaXB0IHNheXMuCgpXZSdyZSBhbHNvIGFibGUgdG8gcmV2aWV3IGNoYW5nZXMgcGVvcGxlIG1ha2UgYmVmb3JlIHRoZXkncmUgYWNjZXB0ZWQgdG8gR2l0SHViLCB3aGljaCBhbGxvd3MgdXMgdG8gcHJvdmlkZSBzb21lIHF1YWxpdHkgY29udHJvbCBpbiB0aGUgYW5hbHlzZXMgd2UgaW50ZW5kIHRvIHB1Ymxpc2guCgojIEhpZ2ggbGV2ZWwgb3ZlcnZpZXcKCkF0IGEgaGlnaCBsZXZlbCwgR2l0SHViIGlzIGEgdG9vbCB0aGF0IGFsbG93cyB1cyB0byBjb2xsYWJvcmF0aXZlbHkgdHJhY2ssIG1hbmFnZSwgYW5kIHVzZSBmaWxlcy4gV2UgY2xvbmUgYSBHaXRIdWIgcmVwb3NpdG9yeSB0byBvdXIgY29tcHV0ZXIsIGFuZCBjaGFuZ2VzIHRvIHRob3NlIGZpbGVzIG9uIG91ciBjb21wdXRlciBhcmUgZGV0ZWN0ZWQgYnkgR2l0LCB0aGUgdW5kZXJseWluZyB2ZXJzaW9uaW5nIHNvZnR3YXJlLiBXZSBjYW4gdXBsb2FkIHRob3NlIGNoYW5nZXMgdG8gR2l0SHViLCB3aGljaCB0cmFja3MgYW5kIHNoYXJlcyB3aGF0IGNoYW5nZXMgd2VyZSBtYWRlLiBUaGUgJ01hc3RlciIgYnJhbmNoIHlvdSBzZWUgYmVsb3cgaXMgd2hhdCBpcyBvbiBHaXRIdWIuIFdoZW4geW91IGNsb25lIHRoZSByZXBvIHRvIHlvdXIgY29tcHV0ZXIsIHlvdSdsbCBiZSBjbG9uaW5nIHRoZSBtYXN0ZXIgYnJhbmNoLCBhbmQgYW55IGNoYW5nZXMgeW91IG1ha2Ugd2lsbCBmb3JrIChzZWUgYmx1ZSkuIFBlb3BsZSB3b24ndCBzZWUgeW91ciBjaGFuZ2VzIHVudGlsIHlvdSBjb21taXQgdG8geW91ciBjbG9uZWQvbG9jYWwgcmVwb3NpdG9yeSBhbmQgJ3B1c2gnIHlvdXIgY2hhbmdlcyBiYWNrIHRvIHRoZSBtYXN0ZXIgYnJhbmNoLiBJbiBvcmRlciBmb3Igc29tZW9uZSB0byBzZWUgeW91ciByZWNlbnRseSBwdXNoZWQgY2hhbmdlcywgdGhleSBuZWVkIHRvIHB1bGwgYWZ0ZXIgeW91ciBjaGFuZ2VzIGFyZSBwdXNoZWQgdG8gbWFzdGVyLiBGb3IgZXhhbXBsZSwgT3JhbmdlIHdvbid0IHNlZSB0aGUgY2hhbmdlcyBCbHVlIG1hZGUgYmVjYXVzZSBPcmFuZ2UgZGlkbid0IHB1bGwgZnJvbSB0aGUgbWFzdGVyIGJyYW5jaCAqYWZ0ZXIqIEJsdWUgY29tbWl0dGVkICYgcHVzaGVkIHRoZWlyIGNoYW5nZXMgYmFjayB0byB0aGUgbWFzdGVyIGJyYW5jaC4KCklmIHdlIHdhbnQgdG8gaW1wbGVtZW50IGEgc3RyaWN0ZXIgc3RhbmRhcmQgb2YgcXVhbGl0eSBjb250cm9sLCB3ZSBjYW4gYWx0ZXJuYXRpdmVseSBjcmVhdGUgYSBicmFuY2ggZnJvbSBtYXN0ZXIgYW5kIHJlcXVlc3Qgb3RoZXJzIHRvIHJldmlldyBvdXIgY29kZSB1c2luZyBhICdwdWxsIHJlcXVlc3QuJyBUaGlzIHdvdWxkIHJlcXVpcmUgb3RoZXJzIHRvIHJldmlldyBvdXIgY29kZSBiZWZvcmUgb3VyIHdvcmsgaXMgJ3B1bGxlZCcgYmFjayBpbnRvIG1hc3Rlci4gVGhlIGRpYWdyYW0gYmVsb3cgc3RpbGwgd29ya3MuIFRob3VnaCwgaW5zdGVhZCBvZiB1cyBwdXNoaW5nIG91ciBmb3JrZWQgY2hhbmdlcyB0byBtYXN0ZXIsIHdlJ3JlIGV4cGxpY2l0bHkgY3JlYXRpbmcgYSBicmFuY2ggYW5kIHJlcXVlc3RpbmcgcGVvcGxlIHRvIGFwcHJvdmUgb3VyIGNoYW5nZXMgYW5kIHB1bGwgaXQgYmFjayBpbnRvIG1hc3RlciwgcmF0aGVyIHRoYW4gKGltcGxpY2l0bHkpIGZvcmtpbmcgb2ZmIG1hc3RlciBhbmQgcHVzaGluZyBvdXIgY2hhbmdlcyBiYWNrIHdpdGhvdXQgcmV2aWV3LgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdC1icmFuY2hlcy1tZXJnZS5wbmcpCgojIEdldHRpbmcgc2V0IHVwCgpCeSBub3csIHlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhbiBpbnZpdGUgZnJvbSBvdXIgRW50ZXJwcmlzZSBHaXRIdWIgdG8gY29sbGFib3JhdGUgb24gdGhlIG9uIGEgc3BlY2lmaWMgcmVwb3NpdG9yeS4gT25jZSB5b3UgY3JlYXRlIGFuIGFjY291bnQsIHlvdSB3aWxsIGJlIGFibGUgdG8gYWNjZXNzIHRoZSBbR2l0SHViIHJlcG9zaXRvcnkuIFRoZSBvbmUgc2hvd24gYmVsb3cgaXMgdGhlIGhpbGxibG9tX2RhdGEgcmVwbywgd2hpY2ggaXMgbm93IHJlbmFtZWQuXShodHRwczovL2dpdC51Y3NmLmVkdS9uZXVyb2xvZ3ktbWVtb3J5YW5kYWdpbmcvKS4gVGhhdCBzaG91bGQgbG9vayBsaWtlIHRoaXM6CgohW10ocGFnZV9pbWFnZXMvZ2l0aHViX2hvbWUucG5nKQoKT25jZSB5b3UgaGF2ZSB5b3VyIGFjY291bnQgc2V0IHVwIGFuZCBhcmUgYWJsZSB0byBhY2Nlc3MgdGhlIGxpbmsgcHJvdmlkZWQgYWJvdmUgdG8gbmF2aWdhdGUgdG8gdGhlIHNwZWNpZmljIHJlcG9zaXRvcnksIGl0J3MgdGltZSB0byBkb3dubG9hZCB0aGUgW0dpdEh1YiBEZXNrdG9wIEFwcF0oaHR0cHM6Ly9kZXNrdG9wLmdpdGh1Yi5jb20vKS4KCkFmdGVyIHRoZSBHaXRIdWIgYXBwIGlzIGRvd25sb2FkZWQsIGdvIHRvIGJhY2sgdG8gdGhlIFtyZXBvc2l0b3J5XShodHRwczovL2dpdC51Y3NmLmVkdS9uZXVyb2xvZ3ktbWVtb3J5YW5kYWdpbmcvKS4gRnJvbSB0aGVyZSwgeW91J2xsIGNsaWNrIHRoZSBncmVlbiBidXR0b24sICdDb2RlLicKCiFbXShwYWdlX2ltYWdlcy9naXRodWJfaG9tZTIucG5nKQoKQW5kIGNsaWNrLCAnT3BlbiB3aXRoIEdpdEh1YiBEZXNrdG9wLicKCiFbXShwYWdlX2ltYWdlcy9naXRodWJfMy5wbmcpCgpUaGF0J2xsIG9wZW4gdGhlIEdpdEh1YiBBcHAgKGlmIHlvdSBhcHByb3ZlIHBlcm1pc3Npb24pLCBhbmQgeW91J2xsIGJlIGdyZWV0ZWQgd2l0aCB0aGlzIHNjcmVlbi4gU2V0IHRoZSBsb2NhbCBwYXRoIHRvIHdoaWNoZXZlciBmb2xkZXIgeW91IHdhbnQgdG8gd29yayBmcm9tLiBGb3IgdGhpcyBpdGVyYXRpb24sIEkgY3JlYXRlZCBhbiAnRW50ZXJwcmlzZScgZm9sZGVyLiBUaG91Z2gsIEknbSB0eXBpY2FsbHkgd29ya2luZyBmcm9tIG15IERvY3VtZW50cyBmb2xkZXIuCgpUaGUgZmluYWwgbG9jYWwgcGF0aCBzaG91bGQgYmUgc29tZXRoaW5nIHNpbWlsYXIgdG8gOgoKLSAgIG9uIE1hYzogL1VzZXJzL3lvdXJ1c2VybmFtZS9Eb2N1bWVudHMvcmVwb25hbWUKLSAgIG9uIFBDOiBDOlVzZXJzXFx5b3VydXNlcm5hbWVcXERvY3VtZW50c1xccmVwb25hbWUKCkZyb20gaGVyZSwgaGl0ICdDbG9uZS4nCgohW10ocGFnZV9pbWFnZXMvZ2l0aHViX3NldHVwLnBuZykKCiMgVGVzdCBpdCBvdXQhCgojIyBPcGVuIHRoZSBsb2NhbCBkaXJlY3Rvcnkgd2hlcmUgeW91IGNsb25lZCB0aGUgcmVwb3NpdG9yeQoKIyMgRmluZCB0aGUgZmlsZSAnd3JpdGVfeW91cl9uYW1lLnR4dCcgaW4gdGhlIHBhdGg6CgotICAgb24gTWFjOiAvVXNlcnMveW91cnVzZXJuYW1lL0RvY3VtZW50cy9yZXBvbmFtZQotICAgb24gUEM6IEM6VXNlcnNcXHlvdXJ1c2VybmFtZVxcRG9jdW1lbnRzXFxyZXBvbmFtZQoKIyMgV3JpdGUgeW91ciBuYW1lLgoKIyMgQ2xvc2UgdGhlIGZpbGUuCgojIyBPcGVuIHRoZSBHaXRIdWIgQXBwLgoKIyMgUHVsbC9mZXRjaCB0aGUgbW9zdCByZWNlbnQgdmVyc2lvbiBvZiB0aGUgbWFzdGVyIGJyYW5jaC4KCi0gICBUaGlzIGlzIHRvIGVuc3VyZSB3ZSBhcmUgd29ya2luZyBmcm9tIHRoZSBtb3N0IHJlY2VudCB2ZXJzaW9uIG9mIHRoZSBtYXN0ZXIgYnJhbmNoLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl90ZXN0aW5nX3B1bGwucG5nKQoKIyMgQ29tbWl0IGNoYW5nZXMgdG8geW91ciBsb2NhbCBtYWNoaW5lLgoKLSAgIFRoaXMgcmVjb3JkcyBjaGFuZ2VzIHlvdSBtYWRlIHRvIHRoZSBjbG9uZWQgdmVyc2lvbiBvZiB0aGUgcmVwb3NpdG9yeS4KLSAgIElmIGxlZnQgYWZ0ZXIgdGhpcyBzdGFnZSwgcGVvcGxlIHdpbGwgbm90IHNlZSB5b3VyIGNoYW5nZXMgaW4gdGhlIHNoYXJlZCByZXBvc2l0b3J5LgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl80LnBuZykKCiMjIEZpbmFsbHksIHB1c2ggeW91ciBjaGFuZ2VzLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl81LnBuZykKCk5vdyBldmVyeW9uZSBjYW4gc2VlIHlvdXIgY2hhbmdlcyBvbiB0aGUgR2l0aHViIHdlYnNpdGUgb3Igb24gdGhlaXIgbG9jYWwgbWFjaGluZSBpZiB0aGV5IHB1bGwvZmV0Y2guIFdlJ3JlIGFibGUgdG8gdHJhY2sgd2hhdCBjaGFuZ2VzIHdlcmUgbWFkZSBhbmQgcmVmZXIgb3IgcmV2ZXJ0IGJhY2sgdG8gcHJldmlvdXMgdmVyc2lvbnMgb2YgdGhlIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5LgoKIyBGb3IgbW9yZSBzdHJpbmdlbnQgcXVhbGl0eSBjb250cm9sCgojIyBDcmVhdGUgYSBuZXcgYnJhbmNoCgotICAgQ2xpY2sgb24gdGhlIGN1cnJlbnQgYnJhbmNoLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3QucG5nKQoKLSAgIE9wdCB0byBjcmVhdGUgbmV3IGJyYW5jaAoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3QyLnBuZykKCi0gICBOYW1lIGJyYW5jaCBhbmQgY29uZmlybQoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3QzLnBuZykKCiMjIFB1Ymxpc2ggdGhlIG5ldyBicmFuY2ggdG8gb3VyIEdpdEh1YiByZXBvLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3Q0LnBuZykKCiMjIE5vdyB5b3UgY2FuIHdvcmsgaW4gdGhpcyBicmFuY2ggYXMgeW91IHdvdWxkIHRoZSBvcmlnaW5hbC4KCi0gICBZb3VyIGNoYW5nZXMgd2lsbCBiZSB0cmFja2VkLCBhbmQgeW91IHdpbGwgbmVlZCB0byBjb21taXQgeW91ciBjaGFuZ2VzIHRvIHRoZSBicmFuY2ggeW91J3JlIHdvcmtpbmcgb24uCgotICAgQ29tbWl0IHlvdXIgY2hhbmdlcyB0byB5b3VyIGxvY2FsIHZlcnNpb24gb2YgdGhlIGJyYW5jaAoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3Q1LnBuZykKCi0gICBQdXNoIHlvdXIgY2hhbmdlcyB0byB0aGUgb25saW5lIHJlcG9zaXRvcnkKCiFbXShwYWdlX2ltYWdlcy9naXRodWJfcHVsbF9yZXF1ZXN0Ni5wbmcpCgojIyBXaGVuIHlvdSdyZSByZWFkeSBmb3Igc29tZW9uZSB0byByZXZpZXcgeW91ciBjb2RlIGFuZCBtZXJnZSB0aGUgYnJhbmNoIHlvdSBjcmVhdGVkIGJhY2sgdG8gdGhlIG9yaWdpbiwgY3JlYXRlIGEgcHVsbCByZXF1ZXN0LgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3Q3LnBuZykKCi0gICBUaGlzIHdpbGwgdGFrZSB5b3UgdG8gdGhlIEdpdEh1YiB3ZWJzaXRlLCB3aGVyZSB5b3UnbGwgYXNzaWduIHlvdXIgcmV2aWV3ZXJzIGFuZCBhc3NpZ25lZXMuIFRoZXknbGwgYmUgdGhlIG9uZXMgd2hvIHJldmlldyB5b3VyIGNvZGUuIExlYXZlIGEgYnJpZWYgZGVzY3JpcHRpb24gb2YgeW91ciByZXF1ZXN0IGFuZCBhIG1vcmUgZGV0YWlsZWQgZXhwbGFuYXRpb24gYmVsb3cgaWYgbmVlZGVkLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3Q4LnBuZykKCiMjIElmIHlvdSB3ZXJlIGFzc2lnbmVkIHRvIGEgcHVsbCByZXF1ZXN0LCB5b3UnbGwgc2VlIHRoZXNlIHBhZ2VzLgoKLSAgIEZpcnN0LCBpdCdsbCB0YWtlIHlvdSB0byB0aGUgY29udmVyc2F0aW9uIHBhZ2UuIEhvd2V2ZXIsIHlvdSdsbCB3YW50IHRvIHRha2UgYSBsb29rIGF0IHRoZSBjaGFuZ2VzIHlvdSd2ZSBiZWVuIGFzc2lnbmVkIHRvIHJldmlldywgd2hpY2ggeW91IGNhbiBmaW5kIGluIHRoZSAnRmlsZXMgY2hhbmdlZCcgdGFiLgotICAgWW91J2xsIHNlZSB0aGUgb25seSBjaGFuZ2UgaW4gdGhpcyBmaWxlIHdhcyBhbiBhZGRlZCBzcGFjZS4gQWRkaXRpb25zIGFyZSBpbiBncmVlbiwgYW5kIGRlbGV0aW9ucy9vbGQgY29kZSBhcmUgaW4gcmVkLgotICAgR28gdG8gdGhlICdSZXZpZXcgY2hhbmdlcycKCiFbXShwYWdlX2ltYWdlcy9naXRodWJfcHVsbF9yZXF1ZXN0OS5wbmcpCgotICAgTGVhdmUgeW91IGNvbW1lbnRzLCByZXF1ZXN0cywgb3IgYXBwcm92ZSB0aGUgcHVsbCByZXF1ZXN0LgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3QxMy5wbmcpCgojIyBPbmNlIHlvdXIgcHVsbCByZXF1ZXN0IGlzIGFwcHJvdmVkLCBtZXJnZSB0aGUgcHVsbCByZXF1ZXN0IGJhY2sgaW50byB0aGUgb3JpZ2luLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3QxMC5wbmcpCgotICAgQ29uZmlybSB0aGUgbWVyZ2UuCgohW10ocGFnZV9pbWFnZXMvZ2l0aHViX3B1bGxfcmVxdWVzdDExLnBuZykKCiMjIEZpbmFsbHksIHlvdSBjYW4gZGVsZXRlIHRoZSBvbGQgYnJhbmNoLgoKLSAgIFRoaXMgaXNuJ3QgbmVjZXNzYXJ5LCBidXQgaXQgY2FuIGhlbHAgdG8ga2VlcCB0aGluZ3Mgb3JnYW5pemVkLgoKIVtdKHBhZ2VfaW1hZ2VzL2dpdGh1Yl9wdWxsX3JlcXVlc3QxMi5wbmcpCgojIFRoYXQncyB0aGUgZW5kIQo=